CREATE PROCEDURE [dbo].[asi_CreatePaymentSchedules]
AS
DECLARE @invKey uniqueidentifier
DECLARE @invLineKey uniqueidentifier
DECLARE @prevInvKey uniqueidentifier
DECLARE @prevInvLineKey uniqueidentifier
DECLARE @paymentTermsKey uniqueidentifier
DECLARE @prevPaymentTermsKey uniqueidentifier
DECLARE @ARAcctKey uniqueidentifier
DECLARE @scheduleLineKey uniqueidentifier
DECLARE @invDate datetime
DECLARE @prevInvDate datetime
DECLARE @termsCode nvarchar(50)
DECLARE @earlyDiscountDays int
DECLARE @earlyDiscountPercent decimal(18,4)
DECLARE @intSize int
DECLARE @prevIntSize int
DECLARE @intType int
DECLARE @prevIntType int
DECLARE @intCount int
DECLARE @prevIntCount int
DECLARE @payments int
DECLARE @fetchStatus int
DECLARE @firstIteration int
DECLARE @acctMethod nchar(1)
DECLARE @prevAcctMethod nchar(1)
DECLARE @extendedPrice decimal(18,4)
DECLARE @currentTotal decimal(18,4)
DECLARE @invoiceTotal decimal(18,4)
DECLARE @currentPayment int
DECLARE @tempARKey uniqueidentifier
DECLARE @acctTotal decimal(18,4)
DECLARE @acctAmount decimal(18,4)
DECLARE @share decimal(18,4)
DECLARE @paidToCurrentGL decimal(18,4)
DECLARE @priority int
DECLARE @paymentDate datetime
DECLARE @firstPaymentDate datetime
DECLARE @scheduledSoFarForInvoice decimal(18,4)
DECLARE @dueAmount decimal(18,4)
DECLARE @scheduledSoFarForInstallment decimal(18,4)
DECLARE @firstPaymentDateTypeCode int
DECLARE @prevFirstPaymentDateTypeCode int
DECLARE @firstPaymentDateOffset int
DECLARE @prevFirstPaymentDateOffset int
DECLARE @firstPaymentDueDate datetime
DECLARE @prevFirstPaymentDueDate datetime
DECLARE @payPriority int
declare @endOfNextMonth datetime
DECLARE @termsTypeYearly int
DECLARE @termsTypeQuarterly int
DECLARE @termsTypeMonthly int
DECLARE @termsTypeWeekly int
DECLARE @termsTypeDaily int
SET @termsTypeYearly = 0
SET @termsTypeQuarterly = 1
SET @termsTypeMonthly = 2
SET @termsTypeWeekly = 3
SET @termsTypeDaily = 4
DECLARE @firstPaymentDateTypeInvoiceDate int
DECLARE @firstPaymentDateTypeNextMonth int
DECLARE @firstPaymentDateTypeEndOfMonth int
DECLARE @firstPaymentDateTypeSpecificDate int
SET @firstPaymentDateTypeInvoiceDate = 0
SET @firstPaymentDateTypeNextMonth = 1
SET @firstPaymentDateTypeEndOfMonth = 2
SET @firstPaymentDateTypeSpecificDate = 3
SET @invoiceTotal = 0
SET @firstIteration = 1
DECLARE @Totals TABLE
(GLAccountKey uniqueidentifier PRIMARY KEY,
Total decimal(18,4),
Share decimal(18,4),
Paid decimal(18,4),
Priority int)
DECLARE Get_Invoices CURSOR FOR
SELECT InvoiceKey, InvoiceLineKey, AccountingMethodCode, PaymentTermsKey = CASE WHEN #tmpInvoice.PaymentTermsKey = '00000000-0000-0000-0000-000000000000' THEN null ELSE #tmpInvoice.PaymentTermsKey END,
InvoiceDate, ExtendedPrice, PaymentTermsName, EarlyDiscountDays, EarlyDiscountPercent, PaymentIntervalSize, PaymentIntervalTypeCode, PaymentIntervalCount,
ARGLAccountKey, FirstPaymentDueDate, FirstPaymentDateTypeCode, FirstPaymentDateOffset, PayPriority
FROM #tmpInvoice
LEFT OUTER JOIN PaymentTerms ON #tmpInvoice.PaymentTermsKey = PaymentTerms.PaymentTermsKey
WHERE #tmpInvoice.InvoiceTypeCode = 'S'
AND ApplyingCredit = 0
AND ARGLAccountKey is not null
ORDER BY InvoiceKey, InvoiceLineKey
SET @prevInvKey = NEWID()
OPEN Get_Invoices
FETCH next from Get_Invoices into
@invKey, @invLineKey, @acctMethod, @paymentTermsKey, @invDate, @extendedPrice, @termsCode, @earlyDiscountDays, @earlyDiscountPercent, @intSize, @intType, @intCount,
@ARAcctKey, @firstPaymentDueDate, @firstPaymentDateTypeCode, @firstPaymentDateOffset, @payPriority
WHILE 1 = 1
BEGIN
SET @fetchStatus = @@FETCH_STATUS
IF @fetchStatus = -1 AND @firstIteration = 1
BREAK
SET @invDate = convert(char(10), @invDate, 101)
IF ((@fetchStatus = -1)) OR ((@prevInvKey != @invKey) AND @firstIteration != 1)
BEGIN
DECLARE FigureShares cursor for
SELECT GLAccountKey, Total
FROM @Totals
OPEN FigureShares
FETCH next from FigureShares into
@tempARKey, @acctTotal
WHILE @@FETCH_STATUS = 0
BEGIN
SET @share = ROUND(@acctTotal / @invoiceTotal, 2)
UPDATE @Totals SET Share = @share WHERE GLAccountKey = @tempARKey
FETCH next from FigureShares into
@tempARKey, @acctTotal
END
CLOSE FigureShares
DEALLOCATE FigureShares
IF @prevPaymentTermsKey IS NULL
SET @payments = 1
ELSE
SET @payments = @prevIntCount
IF @payments = 0
SET @payments = 1
SET @currentPayment = 0
SET @scheduledSoFarForInvoice = 0
SET @firstPaymentDate = @prevInvDate
IF @prevPaymentTermsKey IS NOT NULL
BEGIN
SET @endOfNextMonth = dateadd(dd,-1,DateAdd(mm, DateDiff(mm, 0, @prevInvDate) + 2, 0))
SET @firstPaymentDate =
CASE @prevFirstPaymentDateTypeCode
WHEN @firstPaymentDateTypeInvoiceDate THEN
DATEADD(dd, ISNULL(@prevFirstPaymentDateOffset, 0), @prevInvDate)
WHEN @firstPaymentDateTypeNextMonth THEN
CASE WHEN DATEADD(d, ISNULL(@prevFirstPaymentDateOffset, 0), DateAdd(mm, DateDiff(mm, 0, @prevInvDate) + 1, -1)) > @endOfNextMonth
THEN @endOfNextMonth
ELSE DATEADD(d, ISNULL(@prevFirstPaymentDateOffset, 0), DATEADD(m, DATEDIFF(m, 0, @prevInvDate) + 1, -1))
END
WHEN @firstPaymentDateTypeEndOfMonth THEN
DATEADD(d, -1, DATEADD(m, 1 + DATEDIFF(m, 0, @prevInvDate), 0))
WHEN @firstPaymentDateTypeSpecificDate THEN
ISNULL(@prevFirstPaymentDueDate, @firstPaymentDate)
END
END
SET @dueAmount = ROUND(@invoiceTotal / @payments, 2)
WHILE @currentPayment < @payments
BEGIN
SET @scheduledSoFarForInstallment = 0
IF @prevPaymentTermsKey IS NOT NULL
BEGIN
SET @paymentDate =
CASE @prevIntType
WHEN @termsTypeYearly THEN DATEADD(yy, @prevIntSize * @currentPayment, @firstPaymentDate)
WHEN @termsTypeQuarterly THEN DATEADD(qq, @prevIntSize * @currentPayment, @firstPaymentDate)
WHEN @termsTypeMonthly THEN DATEADD(mm, @prevIntSize * @currentPayment, @firstPaymentDate)
WHEN @termsTypeWeekly THEN DATEADD(wk, @prevIntSize * @currentPayment, @firstPaymentDate)
WHEN @termsTypeDaily THEN DATEADD(dd, @prevIntSize * @currentPayment, @firstPaymentDate)
END
END
ELSE
SET @paymentDate = @firstPaymentDate
SET @currentPayment = @currentPayment + 1
SET @scheduledSoFarForInvoice = @scheduledSoFarForInvoice + @dueAmount
IF (@currentPayment = @payments) AND (@scheduledSoFarForInvoice != @invoiceTotal)
SET @dueAmount = @dueAmount + (@invoiceTotal - @scheduledSoFarForInvoice)
IF UPPER(@prevAcctMethod) = 'A'
BEGIN
DECLARE Account_Info cursor for
SELECT GLAccountKey, Total, Share, Paid, Priority
FROM @Totals
OPEN Account_Info
FETCH next from Account_Info into
@tempARKey, @acctTotal, @share, @paidToCurrentGL, @priority
WHILE @@FETCH_STATUS = 0
BEGIN
SET @acctAmount = ROUND(@dueAmount * @share, 2)
if (@currentPayment = @payments) AND (@acctAmount + @paidToCurrentGL != @acctTotal)
SET @acctAmount = @acctTotal - @paidToCurrentGL
SET @paidToCurrentGL = @paidToCurrentGL + @acctAmount
UPDATE @Totals SET Paid = @paidToCurrentGL WHERE GLAccountKey = @tempARKey
SET @scheduledSoFarForInstallment = @scheduledSoFarForInstallment + @acctAmount
SET @scheduleLineKey = NEWID()
INSERT PaymentScheduleLine(PaymentScheduleLineKey, InvoiceKey, PaymentNumber, DueDate, AmountDue, OutstandingBalance, GLAccountKey, PayPriority)
VALUES(@scheduleLineKey, @prevInvKey, @currentPayment, @paymentDate, @acctAmount, @acctAmount, @tempARKey, @priority)
FETCH next from Account_Info into
@tempARKey, @acctTotal, @share, @paidToCurrentGL, @priority
END
CLOSE Account_Info
DEALLOCATE Account_Info
IF @scheduledSoFarForInstallment != @dueAmount
BEGIN
SET @acctAmount = @acctAmount + (@dueAmount - @scheduledSoFarForInstallment)
UPDATE PaymentScheduleLine SET AmountDue = @acctAmount WHERE PaymentScheduleLineKey = @scheduleLineKey
END
END
ELSE
BEGIN
SET @scheduleLineKey = NEWID()
INSERT PaymentScheduleLine (PaymentScheduleLineKey, InvoiceKey, PaymentNumber, DueDate, AmountDue, OutstandingBalance, PayPriority)
VALUES (@scheduleLineKey, @prevInvKey, @currentPayment, @paymentDate, @dueAmount, @dueAmount, 0)
END
END
IF @fetchStatus = -1 BREAK
IF @fetchStatus = -2 CONTINUE
SET @invoiceTotal = 0;
DELETE @Totals
END
IF (@prevInvKey != @invKey)
BEGIN
SET @prevInvKey = @invKey
SET @prevPaymentTermsKey = @paymentTermsKey
SET @prevInvDate = @invDate
SET @prevIntSize = @intSize
SET @prevIntType = @intType
SET @prevIntCount = @intCount
SET @prevAcctMethod = @acctMethod
SET @prevFirstPaymentDateTypeCode = @firstPaymentDateTypeCode
SET @prevFirstPaymentDateOffset = @firstPaymentDateOffset
SET @prevFirstPaymentDueDate = @firstPaymentDueDate
END
SET @firstIteration = 0
IF @prevInvLineKey is null OR @invLineKey != @prevInvLineKey
BEGIN
SET @invoiceTotal = @invoiceTotal + @extendedPrice
IF UPPER(@acctMethod) = 'A'
BEGIN
SET @currentTotal = null
SELECT @currentTotal = Total, @priority = Priority from @Totals where GLAccountKey = @ARAcctKey
IF @currentTotal IS NULL
BEGIN
INSERT @Totals(GLAccountKey, Total, Share, Paid, Priority)
VALUES (@ARAcctKey, 0, 0, 0, @payPriority)
SET @currentTotal = 0
SET @priority = @payPriority
END
SET @currentTotal = @currentTotal + @extendedPrice
if @payPriority < @priority
SET @priority = @payPriority
UPDATE @Totals SET Total = @currentTotal, Priority = @priority WHERE GLAccountKey = @ARAcctKey
END
END
SET @prevInvLineKey = @invLineKey
FETCH next from Get_Invoices into
@invKey, @invLineKey, @acctMethod, @paymentTermsKey, @invDate, @extendedPrice, @termsCode, @earlyDiscountDays, @earlyDiscountPercent, @intSize, @intType, @intCount,
@ARAcctKey, @firstPaymentDueDate, @firstPaymentDateTypeCode, @firstPaymentDateOffset, @payPriority
END
CLOSE Get_Invoices
DEALLOCATE Get_Invoices
GO